#include "stdafx.h"
#include "scene/cube.h"

namespace natrium {
	namespace scene {
		Cube::Cube(float size) {
			float half = size / 2.0f;

			//prepare the raw data to be stored in the VAO

			float vtx[] = {
				//front
				-half, -half,  half,
				 half, -half,  half,
				 half,  half,  half,
				-half,  half,  half,

				//right
				 half, -half,  half,
				 half, -half, -half,
				 half,  half, -half,
				 half,  half,  half,

				//back
				-half, -half, -half,
				-half,  half, -half,
				 half,  half, -half,
				 half, -half, -half,

				//left
				-half, -half,  half,
				-half,  half,  half,
				-half,  half, -half,
				-half, -half, -half,

				//bottom
				-half, -half,  half,
				-half, -half, -half,
				 half, -half, -half,
				 half, -half,  half,

				//top
				-half,  half,  half,
				 half,  half,  half,
				 half,  half, -half,
				-half,  half, -half
			};

			float normals[] = {
				//front
				 0,  0,  1,
				 0,  0,  1,
				 0,  0,  1,
				 0,  0,  1,

				//right
				 1,  0,  0,
				 1,  0,  0,
				 1,  0,  0,
				 1,  0,  0,

				//back
				 0,  0, -1,
				 0,  0, -1,
				 0,  0, -1,
				 0,  0, -1,

				//left
				-1,  0,  0,
				-1,  0,  0,
				-1,  0,  0,
				-1,  0,  0,

				//bottom
				 0, -1,  0,
				 0, -1,  0,
				 0, -1,  0,
				 0, -1,  0,

				//top
				 0,  1,  0,
				 0,  1,  0,
				 0,  1,  0,
				 0,  1,  0,
			};

			float texCoords[] = {
				//front
				0, 0,
				1, 0,
				1, 1,
				0, 1,

				//right
				0, 0,
				1, 0,
				1, 1,
				0, 1,

				//back
				0, 0,
				1, 0,
				1, 1,
				0, 1,

				//left
				0, 0,
				1, 0,
				1, 1,
				0, 1,

				//bottom
				0, 0,
				1, 0,
				1, 1,
				0, 1,

				//top
				0, 0,
				1, 0,
				1, 1,
				0, 1,
			};

			GLuint idx[] = {
				0, 1, 2, 0, 2, 3,
				4, 5, 6, 4, 6, 7,
				8, 9, 10, 8, 10, 11,
				12, 13, 14, 12, 14, 15,
				16, 17, 18, 16, 18, 19,
				20, 21, 22, 20, 22, 23
			};

			glGenVertexArrays(1, &mVAOHandle); //generate the VAO handle
			glBindVertexArray(mVAOHandle); //set the current VAO

			GLuint buffer[4]; //we're going to need 4 buffers - vtx, normals, texcoord and idx
			glGenBuffers(4, buffer);

			glBindBuffer(GL_ARRAY_BUFFER, buffer[0]); //set current buffer
			glBufferData(GL_ARRAY_BUFFER, sizeof(vtx), vtx, GL_STATIC_DRAW); //fill the buffer
			glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); //packed in groups of 3 floats, not normalized and no stride
			glEnableVertexAttribArray(0); //set position attribute to location 0

			glBindBuffer(GL_ARRAY_BUFFER, buffer[1]); //set current buffer
			glBufferData(GL_ARRAY_BUFFER, sizeof(normals), normals, GL_STATIC_DRAW); //fill the buffer
			glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 0, nullptr); //packed in groups of 3 floats, normalized, no stride
			glEnableVertexAttribArray(1); //set position attribute to location 1

			glBindBuffer(GL_ARRAY_BUFFER, buffer[2]); //set current buffer
			glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW); //fill the buffer
			glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, nullptr); //packed in groups of 2 floats, not normalized, no stride
			glEnableVertexAttribArray(0); //set position attribute to location 2

			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer[3]); //set current buffer
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idx), idx, GL_STATIC_DRAW); //fill the buffer
			mNumElements = sizeof(idx) / sizeof(GLuint);

			glBindVertexArray(0); //reset current VAO, we're done here
		}

		void Cube::render() const {
			glBindVertexArray(mVAOHandle);
			glDrawElements(GL_TRIANGLES, mNumElements, GL_UNSIGNED_INT, nullptr);
		}
	}
}